import CMSElement from '../../utils/CMSElement';
import createDOMString from '../../utils/createDOMString';
import { inRange, toNumOrDefault } from '../../utils/number';
import getColor from '../../utils/getColor';
import createElement from '../../utils/createElement';
import './item';

function renderLabels({ tabs }) {
  return tabs
    .map(label => `<div class="cms-tabs-header_label" title="${label}">${label}</div>`.trim())
    .join('');
}

createElement({
  name: 'cms-tabs',
  props: {
    active: (cur, { tabs }) => {
      const res = inRange(toNumOrDefault(cur, 0), 0);
      return res >= tabs.length ? 0 : res;
    },
  },
  defaultProps: {
    tabs: [],
    active: 0,
  },
  render(props) {
    return createDOMString(props)`
      <style>
        :host {
          width: 100%;
        }
        :host .cms-tabs-header{
          position: relative;
          display: flex;
          overflow: auto;
          background: #fff;
        }
        :host .cms-tabs-header::-webkit-scrollbar {
          width: 0;
          height: 0;
        }
        :host .cms-tabs-header::after {
          content: '';
          position: absolute;
          bottom: 0px;
          left: 0px;
          width: calc(var(--active-width, 0px) * 1px);
          transform: translateX(calc(var(--active-x, 0px) * 1px));
          height: 3px;
          background-color: ${getColor('default', 'light')};
          border-radius: 2px;
          transition: all 0.25s ease-in-out;
        }
        :host .cms-tabs-header .cms-tabs-header_label {
          box-sizing: border-box;
          padding: 0px 10px;
          height: 40px;
          line-height: 40px;
          text-align: center;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
          cursor: pointer;
        }
        :host .cms-tabs-content {
          position: relative;
          overflow: hidden;
          width: 100%;
          background: #fff;
        }
        :host .cms-tabs-content-wrap {
          display: flex;
          transform: translateX(calc(var(--active-index, 0) * -100%));
          transition: transform 0.25s ease-in-out;
        }
        ::slotted(cms-tabs-item) {
          width: 100%;
          flex: 1 0 100%;
        }
        ::slotted(:not(cms-tabs-item)) {
          display: none;
        }
      </style>
      <div class="cms-tabs-header">
        ${renderLabels}
      </div>
      <div class="cms-tabs-content">
        <div class="cms-tabs-content-wrap">
          <slot></slot>
        </div>
      </div>
    `;
  },
  events(target, addEvent, dispatch) {
    function setActive(dom, event = true) {
      const label = dom.getAttribute('title');
      const index = target.props.tabs.findIndex(i => i === label);
      const width = dom.offsetWidth;
      const left = dom.offsetLeft;
      if (target.active !== index) {
        event && dispatch('change', { label, index });
      }
      target.active = index;
      setTimeout(() => {
        target.style.setProperty('--active-width', width);
        target.style.setProperty('--active-x', left);
        target.style.setProperty('--active-index', index);
      });
    }
    const labels = target.shadowRoot.querySelectorAll('.cms-tabs-header_label');
    const dom = labels.item(target.active);
    dom && setActive(dom, false);
    function handleResize() {
      const index = target.props.active;
      const item = labels.item(index);
      item && setActive(item, index, false);
    }
    addEvent(window, 'resize', handleResize);
    addEvent('.cms-tabs-header', 'click', e => {
      setActive(e.target);
    });
  },
  mounted(target) {
    const tabs = [];
    target.querySelectorAll(':scope > *').forEach((dom, index) => {
      if (dom.tagName.toLowerCase() === 'cms-tabs-item') {
        tabs.push(dom.label);
      } else {
        dom.remove();
      }
    });
    target.props.tabs = tabs;
    target.active = target.active;
    target.forceUpdate();
  },
});
